#include <cassert>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

#include "node.h"

int main(int, char**);
std::vector<Token> tokenise(std::ifstream&);
std::vector<Token> removeComments(const std::vector<Token>&);

int main(int argc, char** argv) {
	if (argc != 3) {
		std::cerr << "usage: " << argv[0] << " input output\n";
		return 1;
	}
	std::ifstream input((std::string(argv[1]) + ".bpl").c_str(), std::ios_base::in);
	if (input.is_open() == 0) {
		std::cerr << "ERROR: unable to open input file: '" << argv[1] << ".bpl'\n";
		return 1;
	}
	std::vector<Token> tokens = tokenise(input);
	input.close();
	tokens = removeComments(tokens);
	
	for (std::vector<Token>::size_type i = 0; i < tokens.size(); ++i) {
		std::cout << tokens.at(i).first << ": '" << tokens.at(i).second << "'\n";
	}
	
	// Node* node = new Node(tokens);
	
	// delete node;
	
	return 0;
}

std::vector<Token> tokenise(std::ifstream& input) {
	std::string alphanum("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz");
	std::string brackets("()[]{}");
	std::string symbols("!\"#$%&'*+,-./:;<=>?@\\^`|~");
	std::string whitespace("\t\n ");
	std::vector<Token> tokens;
	unsigned int lineNo = 1;
	while (1) {
		while (whitespace.find(input.peek()) != std::string::npos) {
			if (input.peek() == '\n') {
				++lineNo;
			}
			input.ignore();
		}
		if (input.eof() == true) {
			return tokens;
		}
		std::string string;
		if (alphanum.find(input.peek()) != std::string::npos) {
			string = input.get();
			while (alphanum.find(input.peek()) != std::string::npos) {
				string += input.get();
			}
		} else if (brackets.find(input.peek()) != std::string::npos) {
			string = input.get();
		} else if (symbols.find(input.peek()) != std::string::npos) {
			string = input.get();
			while (symbols.find(input.peek()) != std::string::npos) {
				string += input.get();
			}
		} else {
			assert(0);
		}
		tokens.push_back(make_pair(lineNo, string));
	}
}

std::vector<Token> removeComments(const std::vector<Token>& oldTokens) {
	std::vector<Token> newTokens;
	unsigned int commentLevel = 0;
	unsigned int commentLine = 0;
	for (std::vector<Token>::const_iterator i = oldTokens.begin(); i < oldTokens.end(); ++i) {
		if (commentLine != 0) {
			if ((*i).first == commentLine) {
				continue;
			} else {
				commentLine = 0;
			}
		}
		if (commentLevel == 0) {
			if ((*i).second == "//") {
				commentLine = (*i).first;
			} else if ((*i).second == "/*") {
				++commentLevel;
			} else {
				newTokens.push_back(*i);
			}
		} else if ((*i).second == "/*") {
			++commentLevel;
		} else if ((*i).second == "*/") {
			--commentLevel;
		}
	}
	return newTokens;
}

